/**
 *  @author  scottxp
 *  @contributor xiaody <xiaody09@163.com>
 *  @description  基于默认密码'1234'的百度密语独立加解密模块，源代码来自由scottxp编写的 百度密语 ，由xiaody提取并做了少量修改。
 *  @date  2011-10-25
 */

;(function(){

'use strict';

var Encryptor = {
	s1 : '0123456789abcdef',
	s2 : '{}[]()-_*@!~`,.?',

    encrypt2 : function( str ) {
        str = Encryptor.encrypt( str );
        var newStr = "",
            index,
            i = 0,
            l = str.length;
        for ( ; i < l; i++ ) {
            index = parseInt( str[i], 16 );
            newStr += Encryptor.s2.charAt( index );
        }
        return newStr;
    },

    decrypt2 :  function(s) {
        'use strict';
        var P = [ '0123456789abcdef', '{}[]()-_*@!~`,.?' ];
        for ( var ns = '', i = 0, l = s.length; i < l; i++ ) {
            ns += P[0][P[1].indexOf( s[i] )];
        }
        return Encryptor.decrypt( ns );
    }
};

Encryptor.encrypt = function( str ) {
    if ( str == "" )
        return "";
    str = escape( str );
    var pw = "1234";
    pw = escape(pw);

    var prand = "";
    for ( var i=0, l = pw.length; i < l; i++ ) {
        prand += pw.charCodeAt( i ).toString();
    }
    var sPos = Math.floor( prand.length / 5 );
    var mult = parseInt( prand.charAt(sPos) + prand.charAt(sPos*2) + prand.charAt(sPos*3) + prand.charAt(sPos*4) + prand.charAt(sPos*5) );

    var incr = Math.ceil( pw.length / 2 );
    var modu = Math.pow( 2, 31 ) - 1;
    if (mult < 2) {
        return '';
    }
    var salt = Math.round( Math.random() * 1000000000 ) % 100000000;
    prand += salt;
    while ( prand.length > 10 ) {
        prand = ( parseInt(prand.substring(0, 10)) + parseInt(prand.substring(10, prand.length)) ).toString();
    }
    prand = ( mult * prand + incr ) % modu;

    var enc_chr = "",
        enc_str = "";
    for ( var i = 0, l = str.length; i < l; i++ ) {
        enc_chr = parseInt( str.charCodeAt(i) ^ Math.floor((prand / modu) * 255) );
        if ( enc_chr < 16 )
            enc_str += "0" + enc_chr.toString(16);
        else
            enc_str += enc_chr.toString(16);
        prand = ( mult * prand + incr ) % modu;
    }
    salt = salt.toString( 16 );
    while ( salt.length < 8 )
        salt = "0" + salt;
    enc_str += salt;
    return enc_str;
}

Encryptor.decrypt = function( str ) {
    'use strict';

    var pr = "49505152" + parseInt( str.substring(str.length-8), 16 );
    while ( pr.length > 10 ) {
        pr = ( parseInt(pr.substring(0, 10)) + parseInt(pr.substring(10)) ).toString();
    }

    var asc = 0,
        dstr = '';
    for ( var i = 0, l = str.length-9; i < l; ){
        pr = ( pr * 95051 + 2) % 2147483647;
        asc =  pr * 255 / 2147483647 ^ parseInt( str.substring(i, i+=2),16 );
        dstr += String.fromCharCode( asc );
    }
    return unescape( dstr );
}

var _Miyu = {
    decode : function(str){ /*接口,str为待解密文字,xiaody注*/
        'use strict';
        if (str.substring(0, 4) !== '百度密语' || str.length < 27)
            return;
        str = str.substring( 4 );

        if ( _Miyu.check( str, true ) ) {
            str = str.substring(22,str.lastIndexOf('#'));
            return Encryptor.decrypt2(str).substring(4);
        } else if ( _Miyu.check( str, false ) ) {
            str = str.substring(22);
            return Encryptor.decrypt(str).substring(4);
        }
     },
    encode : function(str) { /*接口,str为待加密文字,xiaody注*/
        str = 'miyu' + str;
        var headmi = Encryptor.encrypt2( '000miyu' );
        var bodymi = Encryptor.encrypt2( str );
        return '百度密语' + headmi + bodymi + '#';
    },
    check : function( str, newFlag ) {
        str = str.substring( 0, 22 );

        if ( arguments.length === 2 ) {
            var func = newFlag ? Encryptor.decrypt2 : Encryptor.decrypt;
            return func( str ) === '000miyu';
        } else {
            return Encryptor.decrypt2( str ) === '000miyu' || Encryptor.decrypt( str ) === '000miyu';
        }
    }

};

window.Miyu = _Miyu;

})();

/**
 *
 *  Base64 encode / decode
 *  From http://www.webtoolkit.info/ , with minor changes by xiaody.
 *
 */
(function() {
'use strict';

// private property
var _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

var Base64 = {

    // public method for encoding
    encode : function ( input ) {
        var output = '',
            chr1,
            chr2,
            chr3,
            enc1,
            enc2,
            enc3,
            enc4,
            i = 0,
            l = input.length;

        input = _utf8_encode( input );

        while ( i < l ) {

            chr1 = input.charCodeAt(i++);
            chr2 = input.charCodeAt(i++);
            chr3 = input.charCodeAt(i++);

            enc1 = chr1 >> 2;
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
            enc4 = chr3 & 63;

            if ( isNaN(chr2) ) {
                enc3 = enc4 = 64;
            } else if ( isNaN(chr3) ) {
                enc4 = 64;
            }

            output = output +
                    _keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
                    _keyStr.charAt(enc3) + _keyStr.charAt(enc4);

        }

        return output;
    },

    // public method for decoding
    decode : function ( input ) {
        'use strict';
        var output = '',
            chr1,
            chr2,
            chr3,
            enc1,
            enc2,
            enc3,
            enc4,
            i = 0,
            l = input.length;

        input = input.replace( /[^A-Za-z0-9\+\/\=]/g, '' );

        while ( i < l ) {

            enc1 = _keyStr.indexOf( input.charAt(i++) );
            enc2 = _keyStr.indexOf( input.charAt(i++) );
            enc3 = _keyStr.indexOf( input.charAt(i++) );
            enc4 = _keyStr.indexOf( input.charAt(i++) );

            chr1 = (enc1 << 2) | (enc2 >> 4);
            chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
            chr3 = ((enc3 & 3) << 6) | enc4;

            output += String.fromCharCode( chr1 );

            if ( enc3 !== 64 ) {
                output += String.fromCharCode(chr2);
            }
            if ( enc4 !== 64 ) {
                output += String.fromCharCode(chr3);
            }

        }

        output = _utf8_decode( output );

        return output;

    }

};

// private method for UTF-8 encoding
function _utf8_encode( string ) {
    string = string.replace( /\r\n/g,"\n" );
    var utftext = '';

    for ( var n = 0, l = string.length; n < l; n++ ) {

        var c = string.charCodeAt(n);

        if ( c < 128 ) {
            utftext += String.fromCharCode(c);
        } else if ( c > 127 && c < 2048 ) {
            utftext += String.fromCharCode((c >> 6) | 192);
            utftext += String.fromCharCode((c & 63) | 128);
        } else {
            utftext += String.fromCharCode((c >> 12) | 224);
            utftext += String.fromCharCode(((c >> 6) & 63) | 128);
            utftext += String.fromCharCode((c & 63) | 128);
        }

    }

    return utftext;
}

// private method for UTF-8 decoding
function _utf8_decode( utftext ) {
    'use strict';
    var string = '',
        c = 0,
        c1 = 0,
        c2 = 0,
        c3 = 0,
        i = 0,
        l = utftext.length;

    while ( i < l ) {

        c = utftext.charCodeAt(i);

        if ( c < 128 ) {
            string += String.fromCharCode(c);
            i++;
        } else if ( c > 191 && c < 224 ) {
            c2 = utftext.charCodeAt(i+1);
            string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
            i += 2;
        } else {
            c2 = utftext.charCodeAt( i + 1 );
            c3 = utftext.charCodeAt( i + 2 );
            string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
            i += 3;
        }

    }

    return string;
}


window.Base64 = Base64;

})();
